#if !defined(_DIRECTDISPLAY_H_INCLUDED_)
#define _DIRECTDISPLAY_H_INCLUDED_

#include <ddraw.h>
#include <memory>
#include "..\GlobalDefs.h"

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

typedef enum
{
	VIDEO_MODE_NONE,
	VIDEO_MODE_RGB555,
	VIDEO_MODE_RGB565,
	VIDEO_MODE_RGB24,
	VIDEO_MODE_RGB32,
	VIDEO_MODE_YUY2,
	VIDEO_MODE_YV12,
} PIXEL_FORMAT;


class CDirectDisplay  
{
public:
	BOOL FillDisplay(DWORD dwColor);
	BOOL InitDirectDraw(HWND hWnd,DWORD dwWidth,DWORD dwHeight,WORD nType);
	BOOL DrawImageFormYUVBuf(PBYTE  in_Y,PBYTE in_U,PBYTE in_V,RECT *Rectdes = NULL);
	BOOL SetDisplayClipper(HWND hWnd);
	void UpdateBounds();
	BOOL UpdataImage(RECT *Rectdes = NULL);
	void ReleaseObject();
	void GetScreenRect(RECT* lpRect);

	inline BOOL IsIntialized() const{
		return m_bIsInitialized;
	}

	CDirectDisplay(HMONITOR hMonitor = NULL, LPGUID lpGuid = NULL);
	~CDirectDisplay();

	inline const LPGUID GetGuid() const{
		return m_pGuid.get();
	}

	inline HMONITOR GetMonitorHandle() const{
		return m_hMonitor;
	}
	
private:	

	std::auto_ptr<GUID> m_pGuid;
	HMONITOR m_hMonitor;
	DWORD	m_Num;
	DWORD	m_Memflag;
	BOOL m_bIsInitialized;

	BOOL FillDisplayYUV(DWORD dwColor);
	BOOL FillDisplayYUV420(DWORD dwColor);
	BOOL FillDisplayRGB(DWORD dwColor);
	BOOL CreateRGBSurface(HWND hWnd,DWORD dwWidth,DWORD dwHeight);	
	BOOL CreateDirectDraw();
	BOOL CreateYUVSurface(HWND hWnd,DWORD dwWidth,DWORD dwHeight);

	HRESULT Present(RECT *Rectdes);
	
	static void fill_yv12_data(BYTE *puc_y, int stride_y, 
								BYTE *puc_u, BYTE *puc_v, int stride_uv, 
								BYTE *puc_out, int width_y, int height_y,
								unsigned int _stride_out);
	static void yuv2rgb_32(BYTE *puc_y, int stride_y, 
								BYTE *puc_u, BYTE *puc_v, int stride_uv, 
								BYTE *puc_out, int width_y, int height_y,
								unsigned int _stride_out);
	static void yuv2rgb_24(BYTE *puc_y, int stride_y, 
								BYTE *puc_u, BYTE *puc_v, int stride_uv, 
								BYTE *puc_out, int width_y, int height_y,
								unsigned int _stride_out);
	static void yuv2rgb_555(BYTE *puc_y, int stride_y, 
								 BYTE *puc_u, BYTE *puc_v, int stride_uv, 
								 BYTE *puc_out,	int width_y, int height_y,
								 unsigned int _stride_out);
	static void yuv2rgb_565(BYTE *puc_y, int stride_y, 
								 BYTE *puc_u, BYTE *puc_v, int stride_uv, 
								 BYTE *puc_out, int width_y, int height_y,
								 unsigned int _stride_out);

	static void yuv2ToYUYV(
		BYTE* lpSrcY, 
		int SrcPitch,
		BYTE* lpSrcU,
		BYTE* lpSrcV, 
		int stride_uv, 
		BYTE* lpDst, 
		int SrcWidth, 
		int SrcHeight,
		unsigned int _stride_out
		);

	HWND  m_hWnd;
	RECT  m_rcWindow;
	DWORD m_nWidth,m_nHeight;

	PIXEL_FORMAT	m_PixelFormat;
	
	LPDIRECTDRAW7       m_pDD;
	LPDIRECTDRAWSURFACE7 m_pddsFrontBuffer;
	LPDIRECTDRAWSURFACE7 m_pddsBackBuffer;
	LPDIRECTDRAWCLIPPER m_pcClipper;

	BOOL			force;
};

#endif // !defined(_DIRECTDISPLAY_H_INCLUDED_)
